import json
import base64
from typing import Optional, List
from core.client import APIClient
from config.settings import Config


class VideoService:
    """视频服务，处理视频URL获取和解析"""
    
    def __init__(self, client: APIClient):
        self.client = client
    
    def get_video_url(self, vid: str, user_product_id: str) -> Optional[str]:
        """根据vid获取视频URL"""
        # 非9位vid视频返回m3u8链接
        if len(vid) != 9:
            return self._get_m3u8_url(vid)
        else:
            # 9位vid的视频直接返回MP4链接
            return self._get_mp4_url(vid, user_product_id)
    
    def _get_m3u8_url(self, vid: str) -> Optional[str]:
        """获取m3u8格式的视频URL"""
        params = {
            'vid': vid,
            'siteid': Config.FIXED_PARAMS['siteid'],
        }
        
        response = self.client.get(
            Config.API_ENDPOINTS['m3u8_url'],
            params=params,
            headers=Config.M3U8_HEADERS
        )
        
        try:
            # 处理特殊的响应格式
            text = response.text.replace('null(', '')[:-1]
            data = json.loads(text)
            return data["copies"][1]["playurl"]
        except (KeyError, IndexError, json.JSONDecodeError):
            return None
    
    def _get_mp4_url(self, vid: str, user_product_id: str) -> Optional[str]:
        """获取MP4格式的视频URL"""
        while True:
            # 获取播放token
            params = {
                'id': '1',
                'userProductId': user_product_id,
                'vid': vid,
                'isAllowAudition': '0',
            }
            
            response = self.client.get(
                Config.API_ENDPOINTS['player_token'],
                params=params,
                allow_redirects=False
            )
            
            try:
                token = response.json()["data"]["token"]
            except KeyError:
                continue
            
            # 获取加密URL
            params = {
                "vid": vid,
                "token": token
            }
            
            response = self.client.get(
                Config.API_ENDPOINTS['mp4_url'],
                params=params
            )
            
            try:
                data = response.json()
                enc_urls = []
                
                # 收集所有可能的加密URL
                for quality in Config.VIDEO_QUALITIES:
                    if quality in data["data"]["play_info"]:
                        for i in range(3):
                            try:
                                enc_url = data["data"]["play_info"][quality]["cdn_list"][i]["enc_url"]
                                enc_urls.append(enc_url)
                            except (KeyError, IndexError):
                                continue
                
                # 尝试解密URL
                for enc_url in enc_urls:
                    url = self._decode_encrypted_url(enc_url)
                    if url != -1:
                        return url
                        
            except (KeyError, json.JSONDecodeError):
                continue
                
            return None
    
    @staticmethod
    def _decode_encrypted_url(enc_url: str) -> str:
        """解密加密的视频URL"""
        try:
            encoded_str = enc_url.replace("bjcloudvod://", '')
            
            # 修复base64填充
            if len(encoded_str) % 4 != 0:
                encoded_str += "=" * (4 - len(encoded_str) % 4)
            
            # 解码base64
            decoded_bytes = base64.b64decode(encoded_str)
            decoded_str = decoded_bytes.decode("utf-8")
            
            # 解密算法
            n = ord(decoded_str[0]) % 8
            decoded_str = decoded_str[1:]
            
            result = []
            for index, char in enumerate(decoded_str):
                p = index % 4 * n + index % 3 + 1
                result.append(chr(ord(char) - p))
            
            return ''.join(result)
            
        except Exception:
            return -1